package com.business.dynamic.service.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.business.common.dto.R;
import com.business.common.enums.BusinessExceptionEnum;
import com.business.common.exception.BusinessException;
import com.business.common.utils.PageUtils;
import com.business.common.utils.StrKit;
import com.business.user.entity.UserDetailsDto;
import com.business.dynamic.entity.Dynamic;
import com.business.dynamic.entity.DynamicComment;
import com.business.dynamic.entity.DynamicMessage;
import com.business.dynamic.entity.vo.DynamicCommentVo;
import com.business.dynamic.mapper.DynamicCommentMapper;
import com.business.dynamic.mapper.DynamicMapper;
import com.business.dynamic.service.DynamicCommentService;
import com.business.dynamic.service.DynamicMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


/**
 * 动态评论表:业务接口实现类
 *
 * @author chenjiehong
 * @date 2019-11-29 15:15:38
 * @since 1.0
 */
@Service
public class DynamicCommentServiceImpl implements DynamicCommentService {

    @Autowired
    private DynamicCommentMapper dynamicCommentMapper;

    @Autowired
    private DynamicMapper dynamicMapper;

    @Autowired
    private DynamicMessageService dynamicMessageService;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private PlatformTransactionManager transactionManager;

    private ThreadPoolExecutor pool = new ThreadPoolExecutor(9, 30, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

    private Logger logger = LoggerFactory.getLogger(DynamicCommentServiceImpl.class);


    @Override
    public Integer add(DynamicComment dynamicComment) {
        Integer commentQuantity = dynamicMapper.getDynamicQuantity(dynamicComment.getDynamicId(), "comment_quantity");
        if (commentQuantity == null) {
            throw new BusinessException(BusinessExceptionEnum.DYNAMIC_NOT_EXIST);
        }
        //异步
        pool.execute(() -> {
            //异步情况下 @Transaction 没有效果
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别，开启新事务，这样会比较安全些。
            TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
            try {
                dynamicComment.setCreateTime(new Date());
                Integer result = dynamicCommentMapper.insert(dynamicComment);
                if (result > 0) {
                    Dynamic dynamic = new Dynamic();
                    dynamic.setId(dynamicComment.getDynamicId());
                    dynamic.setCommentQuantity(commentQuantity + 1);
                    dynamicMapper.updateById(dynamic);

                    //添加消息
                    DynamicMessage dynamicMessage = new DynamicMessage();
                    dynamicMessage.setType(0);
                    dynamicMessage.setItemId(dynamicComment.getId());
                    dynamicMessage.setDynamicId(dynamicComment.getDynamicId());
                    dynamicMessage.setFromUserId(dynamicComment.getUserId());

                    Integer dynamicUserId = dynamicMapper.getDynamicUserId(dynamicComment.getDynamicId());
                    //发送给回复者
                    if (dynamicComment.getToUserId() != null && dynamicUserId != dynamicComment.getToUserId()) {
                        dynamicMessage.setUserId(dynamicComment.getToUserId());
                        dynamicMessageService.add(dynamicMessage);
                    }
                    //发送给动态的作者
                    if(dynamicComment.getUserId() != dynamicUserId){
                        dynamicMessage.setUserId(dynamicUserId);
                        dynamicMessageService.add(dynamicMessage);
                    }

                }
                //提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                //回滚 事务
                transactionManager.rollback(status);
            }

        });
        return commentQuantity + 1;
    }

    @Override
    public Integer delete(Integer id) {
        DynamicComment dynamicComment = dynamicCommentMapper.selectById(id);
        if (dynamicComment == null) {
            throw new BusinessException(BusinessExceptionEnum.COMMENT_NOT_EXIST);
        }
        Integer commentQuantity = dynamicMapper.getDynamicQuantity(dynamicComment.getDynamicId(), "comment_quantity");
        if (commentQuantity == null) {
            throw new BusinessException(BusinessExceptionEnum.DYNAMIC_NOT_EXIST);
        }
        //异步
        pool.execute(() -> {
            //异步情况下 @Transaction 没有效果
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别，开启新事务，这样会比较安全些。
            TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
            try {
                Integer result = dynamicMapper.deleteById(id);
                if (result > 0) {
                    Dynamic dynamic = new Dynamic();
                    dynamic.setId(dynamicComment.getDynamicId());
                    dynamic.setCommentQuantity(commentQuantity - 1);
                    dynamicMapper.updateById(dynamic);
                    //删除消息
                    dynamicMessageService.delete(dynamicComment.getId(), 0);
                }
                //提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                //回滚 事务
                transactionManager.rollback(status);
            }
        });
        return commentQuantity - 1;
    }

    @Override
    public PageUtils queryPage(Page<DynamicComment> page, Integer dynamicId, Integer userId) {
        Integer dynamicUserId = dynamicMapper.getDynamicUserId(dynamicId);
        if (dynamicUserId == null) {
            throw new BusinessException(BusinessExceptionEnum.DYNAMIC_NOT_EXIST);
        }
        Wrapper<DynamicComment> wrapper = new EntityWrapper<>();
        wrapper.eq("dynamic_id", dynamicId);
        wrapper.orderBy("id", true);//时间排序
        List<DynamicCommentVo> result = dynamicCommentMapper.queryPage(page, wrapper);

        Set<Integer> ids = new HashSet<>();
        for (DynamicCommentVo dynamicComment : result) {
            ids.add(dynamicComment.getUserId());
            if (dynamicComment.getToUserId() != null) {
                ids.add(dynamicComment.getToUserId());
            }
            //判断是否是私密评论 如果是私密评论就只能发布者可看
            if (userId == null || (dynamicComment.getVisibility() == 1 && userId != dynamicUserId && dynamicComment.getUserId() != userId)) {
                //替换字符
                dynamicComment.setContent(StrKit.strToHideStr(dynamicComment.getContent(), '*'));
            }
        }
        //获取用户信息
        Map<Integer, UserDetailsDto> nameMap = userService.getUserNameList(ids);
        for (DynamicCommentVo dynamicComment : result) {
            UserDetailsDto userDto = nameMap.get(dynamicComment.getUserId());
            if (userDto != null) {
                dynamicComment.setUserRealName(userDto.getRealName());
                dynamicComment.setUserHeadUrl(userDto.getHeadUrl());
            } else {
                dynamicComment.setUserRealName("未设置");
            }
            if (dynamicComment.getToUserId() != null) {
                userDto = nameMap.get(dynamicComment.getToUserId());
                if (userDto != null) {
                    dynamicComment.setToUserRealName(userDto.getRealName());
                    dynamicComment.setToUserHeadUrl(userDto.getHeadUrl());
                } else {
                    dynamicComment.setToUserRealName("未设置");
                }
            }
        }
        PageUtils pageUtils = new PageUtils(result, page.getTotal());
        return pageUtils;
    }

}